package com.gitee.apecome.core.remote.net.netty.client;

import com.gitee.apecome.core.remote.ApeRpcFactory;
import com.gitee.apecome.core.remote.bean.ApeRpcRequest;
import com.gitee.apecome.core.remote.bean.ApeRpcResponse;
import com.gitee.apecome.core.remote.code.NettyDecoder;
import com.gitee.apecome.core.remote.code.NettyEncoder;
import com.gitee.apecome.core.remote.code.serialize.impl.HessianSerializer;
import com.gitee.apecome.core.remote.net.netty.client.handler.NettyClientHandler;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;


public class NettyConnectClient implements Client{

    private Channel channel;
    private String hostName;
    private Integer port;

    public NettyConnectClient(String hostName, Integer port) {
        this.hostName = hostName;
        this.port = port;
        start();
    }

    public static NettyConnectClient newInstance(String hostName, Integer port) {
        return new NettyConnectClient(hostName, port);
    }

    void start() {
        EventLoopGroup boss = new NioEventLoopGroup();
        Bootstrap b = new Bootstrap();
        b.group(boss)
                .channel(NioSocketChannel.class)
                .handler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel socketChannel) throws Exception {
                        socketChannel.pipeline()
                                .addLast(new NettyEncoder(ApeRpcRequest.class, HessianSerializer.newInstance()))
                                .addLast(new NettyDecoder(ApeRpcResponse.class, HessianSerializer.newInstance()))
                                .addLast(new NettyClientHandler(ApeRpcFactory.newInstance()));
                    }
                });
        try {
            ChannelFuture f = b.connect(hostName, port).sync();
            f.addListener(new ChannelFutureListener() {
                @Override
                public void operationComplete(ChannelFuture channelFuture) throws Exception {
                    if (channelFuture.isSuccess()) {
                        System.out.println("连接成功");
                    }
                }
            });
            this.channel = f.channel();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void asyncRequest(ApeRpcRequest request) {
        System.out.println("发送消息");
        try {
            channel.writeAndFlush(request).sync();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
